package servlet;

import java.io.File;
import java.io.IOException;
import java.sql.Date;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileItemFactory;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;

import service.ActorService;
import service.UserService;
import util.DateUtil;
import util.ExpindConstants;
import util.RegexUtil;
import util.Title;
import util.TitleUtil;

import domain.Actor;
import domain.User;
import ex.DatabaseException;
import ex.RegistrationFailedException;


public class EditProfile extends HttpServlet {
	
	UserService userService=new UserService();
	ActorService actorService=new ActorService();
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		HttpSession session=request.getSession();
		if(session.getAttribute("user")!=null){
			User user=(User) session.getAttribute("user");
			if(user!=null)
			{
				String action=request.getParameter("action");
				if(!RegexUtil.isNullOrEmpty(action)){
					if(action.equalsIgnoreCase("save")){
						request.getAttribute("firstname");
					}
					else{
						response.sendRedirect("home");
					}
				}
				else{
					
					Map<Title,Boolean> hasTitles=TitleUtil.getTitlesByUser(user);
					
					request.setAttribute("hasTitles", hasTitles);
					
					RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/user/user-edit.jsp");
					if (dispatcher != null) dispatcher.forward(request, response);
				}
			}
			else{
				response.sendRedirect("home");
			}
		}
		else{
			response.sendRedirect("home");
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		User tmpUser=null;
		request.setCharacterEncoding("UTF-8");
		HttpSession session=request.getSession();
		try{			
			if(session.getAttribute("user")!=null){
				User user=(User) session.getAttribute("user");
				if(user!=null)
				{
					// Create a factory for disk-based file items
					FileItemFactory factory = new DiskFileItemFactory();
					// Create a new file upload handler
					ServletFileUpload upload = new ServletFileUpload(factory);
					// Parse the request
					List<FileItem> items = upload.parseRequest(request); 
					Map<String, String> fieldMap = new HashMap<String, String>();
					// Process the uploaded items
					Iterator<FileItem> iter = items.iterator();
					String destination = "";
					while (iter.hasNext()) {
						FileItem item = (FileItem) iter.next();
						if(item.isFormField()){
							String value=item.getString("UTF-8").trim();
							if(item.getFieldName().equalsIgnoreCase("title") && fieldMap.containsKey("title") ){
								value=value+"#" +fieldMap.get("title");
							}
							fieldMap.put(item.getFieldName(),value );
						}else{
							String fileName="/" + fieldMap.get("email") + ".jpeg";
							destination = getServletContext().getRealPath("/jsp/user/images/user"+ fileName);
							File uploadedFile = new File(destination);
							item.write(uploadedFile);
							destination=ExpindConstants.rootPath + "/jsp/user/images/user"+ fileName;
						}
					}					
					
					tmpUser=user;
					Map<Title,Boolean> hasTitles=TitleUtil.getTitlesByUser(user);
					
					request.setAttribute("hasTitles", hasTitles);
					
					String firstName=fieldMap.get("firstname");
					String surname=fieldMap.get("surname");
					//String image=request.getParameter("image");
					String imageURL=destination;		
					Date birthDate=getDate(fieldMap);
					String city=fieldMap.get("city");
					String tel=fieldMap.get("tel");
					String description=fieldMap.get("description");
					boolean availabilibty=fieldMap.get("availability")!=null && !fieldMap.get("availability").equals("");
					
					//storing what titles the user has marked through bitwise operation
					int titleBits = getTitleBits(fieldMap.get("title"));
					if(titleBits!=-1){
						
						boolean actorSelected=(titleBits & TitleUtil.actor_bit)==TitleUtil.actor_bit;
						
						if(actorSelected){
							String heightString=fieldMap.get("height");
							int height=0;
							if(!RegexUtil.isParsableToInt(heightString)){
								throw new RegistrationFailedException("Height is not in correct format!");
							}
							else{
								height=Integer.parseInt(heightString);
							}
							String weightString=fieldMap.get("weight");
							int weight=0;
							if(!RegexUtil.isParsableToInt(weightString)){
								throw new RegistrationFailedException("Weight is not in correct format!");
							}
							else{
								weight=Integer.parseInt(weightString);
							}
							String hairColor=fieldMap.get("hair");
							String skinColor=fieldMap.get("skin");
							String eyeColor=fieldMap.get("eyes");
							Actor actor=user.getActorFeatures();
							if(actor!=null){
								actor.setHeight(height);
								actor.setWeight(weight);
								actor.setHairColor(hairColor);
								actor.setSkinColor(skinColor);
								actor.setEyeColor(eyeColor);
								
								user.setActorFeatures(actor);
							}
							else
							{
								actor=new Actor(-1, hairColor, eyeColor,skinColor, height, weight);
								user.setActorFeatures(actor);
							}							
						}
						else
						{
							Actor actor=user.getActorFeatures();
							if(actor!=null){
								actorService.deleteActor(actor);
								user.setActorFeatures(null);
							}							
						}
					}
					user.setFirstName(firstName);
					user.setLastName(surname);
					user.setDateOfBirth(birthDate);
					user.setImageURL(imageURL);
					user.setSummary(description);
					user.setCity(city);
					user.setTel(tel);
					user.setTitle(titleBits);
					user.setAvailable(availabilibty);
					userService.updateUser(user);
					user= userService.authenticateUser(user.getEmail(), user.getPassword());
					session.setAttribute("user", user);
					response.sendRedirect("user?who=me");
				}
			}
		}
		catch (RegistrationFailedException e) {
			request.setAttribute("updateError", e.getMessage());
			
			RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/user/user-edit.jsp");
			if (dispatcher != null) dispatcher.forward(request, response);
		}
		catch (DatabaseException e) {
			request.setAttribute("updateError", e.getMessage());
			RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/user/user-edit.jsp");
			if (dispatcher != null) dispatcher.forward(request, response);
		}
		catch (ParseException e) {
			request.setAttribute("updateError", e.getMessage());
			RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/user/user-edit.jsp");
			if (dispatcher != null) dispatcher.forward(request, response);
		}
		catch (Exception e) {
			request.setAttribute("updateError", "A general error occured:" + e.getMessage());
			RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/user/user-edit.jsp");
			if (dispatcher != null) dispatcher.forward(request, response);
		}
	}
	
	protected Date getDate(Map<String, String> fieldMap) throws ParseException{
		String day= fieldMap.get("day");
		String month=fieldMap.get("month");
		String year=fieldMap.get("year");
		
		String datetimeString=year+" " + month + " " + day;
		return DateUtil.convertStringToDateYYYYMMDD(datetimeString);
	}
	
	protected int getTitleBits(String titleNames) throws ParseException{
		String[] titles = RegexUtil.splitDiyez(titleNames);
		
		//storing what titles the user has marked through bitwise operation
		int titleBits = 0x00;
		if (titles != null) {
			Title title;
			for (int i = 0; i < titles.length; i++)	{
				String value=titles[i];
				if(!RegexUtil.isNullOrEmpty(value)){
					title=TitleUtil.getTitleByTitleName(value);
					if(title!=null){
						titleBits |= title.getTitleBit();
					}
				}
			}
			return titleBits;
		}
		return -1;
	}

}
